package com.itc.bpm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itc.bpm.bean.BpmProcessCategory;
import com.itc.bpm.bean.BpmProcessInstanceExt;
import com.itc.bpm.bean.BpmProcessTaskExt;
import com.itc.bpm.dto.BpmFactoryCountDto;
import com.itc.bpm.framework.factory.vo.BpmStartVO;
import com.itc.bpm.framework.service.ProcessInstanceService;
import com.itc.bpm.mapper.BpmProcessInstanceExtMapper;
import com.itc.bpm.service.BpmProcessCategoryService;
import com.itc.bpm.service.BpmProcessInstanceExtService;
import com.itc.bpm.service.BpmProcessTaskExtService;
import com.itc.bpm.vo.BpmProcessUpVo;
import com.itc.common.core.domain.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
public class BpmProcessInstanceExtServiceImpl extends ServiceImpl<BpmProcessInstanceExtMapper, BpmProcessInstanceExt> implements BpmProcessInstanceExtService {
    @Autowired(required = false)
    BpmProcessInstanceExtMapper bpmProcessInstanceExtMapper;

    @Autowired
    @Lazy
    private ProcessInstanceService processInstanceService;

    @Autowired
    BpmProcessCategoryService bpmProcessCategoryService;

    @Override
    public void updateStatus(String processInstanceId, Integer status) {
        // 完成状态，校验流程是否结束
        BpmProcessInstanceExt processInstanceExt = bpmProcessInstanceExtMapper.selectOne(new LambdaQueryWrapper<BpmProcessInstanceExt>().eq(BpmProcessInstanceExt::getProcessInstanceId,processInstanceId));
        processInstanceExt.setStatus(status);
        // 记录结束时间
        processInstanceExt.setEndTime(new Date());
        bpmProcessInstanceExtMapper.updateById(processInstanceExt);
    }

    @Override
    public BpmProcessInstanceExt getProcessInstanceExtByInstanceId(String processInstaneId) {
        BpmProcessInstanceExt processInstanceExt = bpmProcessInstanceExtMapper.selectOne(new LambdaQueryWrapper<BpmProcessInstanceExt>().eq(BpmProcessInstanceExt::getProcessInstanceId,processInstaneId));
        return processInstanceExt;
    }

    @Override
    public Boolean checkServiceIsExists(String businessKey,String modelId) {
        Integer num  = bpmProcessInstanceExtMapper.checkServiceIsExists(businessKey,modelId);
        if(num>0){
            return false;
        }
        return true;
    }

    @Override
    public R<List<BpmFactoryCountDto>> countProcessInstanceInfo() {
        List<BpmProcessCategory> categories = bpmProcessCategoryService.list(new LambdaQueryWrapper<BpmProcessCategory>().eq(BpmProcessCategory::getParentId,0L).eq(BpmProcessCategory::getDelFlag,0).orderByAsc(BpmProcessCategory::getOrderNo));
        //根据分类查询汇总统计
        List<BpmFactoryCountDto> list = new ArrayList<>();
        for(BpmProcessCategory category:categories){
            BpmFactoryCountDto dto = bpmProcessInstanceExtMapper.countProcessInstanceInfo(category.getCode());
            if(dto==null) {
                dto = new BpmFactoryCountDto();
                dto.setProgressNum(0);
                dto.setCompleteNum(0);
            }

            dto.setCode(category.getCode());
            dto.setName(category.getName());
            list.add(dto);
        }
        return R.ok(list);
    }


    @Transactional
    @Override
    public R upDwon(BpmProcessUpVo bpmFormDesign) {
        BpmProcessInstanceExt processInstanceExt = this.getProcessInstanceExtByInstanceId(bpmFormDesign.getProcessInstanceId());
        if(processInstanceExt==null){
            return R.fail("流程实例不存在，不可进行升降级操作!");
        }
        if(processInstanceExt.getStatus()!=0){
            return R.fail("当前流程不可进行升降级操作!");
        }
        // 取消历史流程，发起新的流程
        processInstanceService.cacenProcessInstance(bpmFormDesign.getProcessInstanceId());
        BpmStartVO bpmStartVO = new BpmStartVO();
        bpmStartVO.setModelId(bpmFormDesign.getModelId());
        bpmStartVO.setFlightNumber(processInstanceExt.getFlightNumber());
        bpmStartVO.setBusinessKey(processInstanceExt.getServiceId());
        bpmStartVO.setData(new HashMap<>());
        String processInstanceId = processInstanceService.createSignProcessInstance(bpmStartVO);
        return R.ok(processInstanceId);
    }

    @Override
    public BpmProcessInstanceExt findModelByServiceId(Long id, String serviceId) {
        return this.getOne(new LambdaQueryWrapper<BpmProcessInstanceExt>().eq(BpmProcessInstanceExt::getServiceId,serviceId).eq(BpmProcessInstanceExt::getBpmModelId,id).orderByDesc(BpmProcessInstanceExt::getCreateTime).last("limit 1"));
    }

    @Override
    public BpmProcessInstanceExt findModelByModelKey(String bpmKey, String serviceId) {
        return this.getOne(new LambdaQueryWrapper<BpmProcessInstanceExt>().eq(BpmProcessInstanceExt::getServiceId,serviceId).eq(BpmProcessInstanceExt::getBpmKey,bpmKey).orderByDesc(BpmProcessInstanceExt::getCreateTime).last("limit 1"));
    }
}
